package org.jeecg.common.datasource.utils;

import org.jeecg.common.COSMOS;
import org.jeecg.common.datasource.enums.DataSourceType;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 数据库函数转化工具
 * @author lenovo
 *
 */
public class DBFUtil {

	/**
	 * 行转列，以逗号分隔
	 * @return
	 */
	public static String listToCell(String fieldName, String sortInfo) {
		StringBuffer fun = new StringBuffer();
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			fun.append("(GROUP_CONCAT(DISTINCT " + fieldName + " ORDER BY " + sortInfo + ")) ");
		} else {
			fun.append("(listagg(TO_CHAR(" + fieldName + "), ',') WITHIN GROUP (ORDER BY " + sortInfo + ")) ");
		}
		return fun.toString();
	}
	
	/**
	 * 主键名称
	 * @return
	 */
	public static String primaryName() {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE) || "dm".equalsIgnoreCase(COSMOS.DB_TYPE) || "kingbase8".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			// 自动生成
			return "";
		}
		if ("postgresql".equalsIgnoreCase(COSMOS.DB_TYPE)){
			// 自动生成
			return "";
		}
		return "id, ";
	}
	
	/**
	 * 主键序列 多用于select id,
	 * @param seqName
	 * @return
	 */
	public static String primarySeqName(String seqName) {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE) || "dm".equalsIgnoreCase(COSMOS.DB_TYPE) || "kingbase8".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			// 自动生成
			return "";
		}
		if ("postgresql".equalsIgnoreCase(COSMOS.DB_TYPE)){
			// 自动生成
			return "";
		}
		return seqName + ".nextval id, ";
	}

	/**
	 * 获取主键自增ID值 用于insert数据库
	 * @param seqName
	 * @return
	 */
	public static String getPrimarySeqValue(String seqName) {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE) || "dm".equalsIgnoreCase(COSMOS.DB_TYPE) || "kingbase8".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			// 自动生成
			return "";
		}
		return seqName + ".nextval,";
	}
	
	/**
	 * 获取自增id
	 * @param seqName 序列表名
	 * @return
	 */
	public static String getPrimarySeq(String seqName) {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE) || "dm".equalsIgnoreCase(COSMOS.DB_TYPE) || "kingbase8".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			// 自动生成
			return "";
		}
		if ("postgresql".equalsIgnoreCase(COSMOS.DB_TYPE)){
			// 自动生成
			return "";
		}
		return "select " + seqName + ".nextval from dual";
	}
	
	public static String concatStr(String...args) {
		StringBuffer fun = new StringBuffer();
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			// 自动生成
			fun.append("concat( ");
			for(int i=0; i<args.length; i++) {
				if(i > 0) {
					fun.append(" , ");
				}
				fun.append(args[i]);
			}
		} else {
			fun.append(" (");
			for(int i=0; i<args.length; i++) {
				if(i > 0) {
					fun.append(" || ");
				}
				fun.append(args[i]);
			}
		}
		fun.append(") ");
		return fun.toString();
	}
	
	/**
	 * 时间转字符串
	 * @param fieldName	字段
	 * @param pattern	格式
	 * @return
	 */
	public static String dateToChar(String fieldName, String pattern) {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			return "date_format(" + fieldName + ",'" + getDatePattern(pattern) + "') ";
		}
		return "to_char(" + fieldName + ", '" + getDatePattern(pattern) + "') ";
	}
	
	/**
	 * 字符串转时间
	 * @param fieldName	字段
	 * @param pattern	格式
	 * @return
	 */
	public static String charToDate(String fieldName, String pattern) {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			return "STR_TO_DATE(" + fieldName + ",'" + getDatePattern(pattern) + "') ";
		}
		return "to_date(" + fieldName + ", '" + getDatePattern(pattern) + "') ";
	}
	
	private static String getDatePattern(String pattern) {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			// 自动生成 yyyy-MM-dd
			pattern = pattern.replace("yyyy", "%Y").replace("MM", "%m").replace("dd", "%d").replace("hh24", "%H").replace("hh", "%H").replace("mi", "%i").replace("ss", "%s");
		}
		return pattern;
	}

	/**
	 * nvl转ifNull
	 * @param fieldName	字段1
	 * @param elseField	字段2
	 * @return
	 */
	public static String nvlToIfnull(String fieldName, String elseField) {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			return "ifnull(" + fieldName + ", "+ elseField + ") ";
		}
		return "nvl(" + fieldName + ", "+ elseField + ") ";
	}

	/**
	 * 正则表达式（不匹配）
	 * @param fieldName	字段名称
	 * @param regexp	正则表达式
	 * @return
	 */
	public static String regexp(String fieldName, String regexp) {
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			return fieldName + " not regexp '" + regexp + "' ";
		}
		return "not regexp_like( " + fieldName + ", '"+ regexp + "') ";
	}
	
	/**
	 * 将Map可以统一转化为大写
	 * @param mapObj
	 */
	@SuppressWarnings("unchecked")
	public static void keyToLowerCase(Object mapObj) {
		if(mapObj == null) {
			return;
		}
		
		if(mapObj instanceof List) {
			List<?> mapList = (List<?>) mapObj;
			mapList.forEach(n -> {
				toLowerCase((Map<String, Object>)n);
			});
		} else {
			toLowerCase((Map<String, Object>)mapObj);
		}
    }
	
    private static void toLowerCase(Map<String, Object> map) {
    	Iterator<String> iterator = map.keySet().iterator();
    	Map<String, Object> newMap = new HashMap<String, Object>();
    	while(iterator.hasNext()) {
    		String key = iterator.next();
    		Object value = map.get(key);
    		newMap.put(key.toUpperCase(), value);
    	}
    	
    	iterator = newMap.keySet().iterator();
    	while(iterator.hasNext()) {
    		String key = iterator.next();
    		Object value = newMap.get(key);
    		map.put(key.toUpperCase(), value);
    	}
    }

    public static String findInSet(String fieldName, Long value){
		StringBuffer fun = new StringBuffer();
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			fun.append( "Find_in_set(");
			fun.append(value);
			fun.append(" , ");
			fun.append(fieldName);
			fun.append(" )");
		} else {
			fun.append(" instr(','||");
			fun.append(fieldName);
			fun.append(" ||',',',");
			fun.append(value);
			fun.append(",'");
			fun.append(" ) > 0");
		}
		return fun.toString();
	}

	public static String findObjectInSet(String fieldName, Object value){
		StringBuffer fun = new StringBuffer();
		if ("MySQL".equalsIgnoreCase(COSMOS.DB_TYPE)) {
			fun.append( "Find_in_set(");
			fun.append(value);
			fun.append(" , ");
			fun.append(fieldName);
			fun.append(" )");
		} else {
			fun.append(" instr(','||");
			fun.append(fieldName);
			fun.append(" ||',',',' || ");
			fun.append(value);
			fun.append(" || ','");
			fun.append(" ) > 0");
		}
		return fun.toString();
	}

	/**
	 * 获取数据库类型
	 * @return
	 */
	public static String getDbType(String driverClass){
		String dbType = null;
		if(driverClass.toLowerCase().contains(DataSourceType.MYSQL.getType())){
			dbType = DataSourceType.MYSQL.getType();
		} else if(driverClass.toLowerCase().contains(DataSourceType.ORACLE.getType())){
			dbType = DataSourceType.ORACLE.getType();
		} else if(driverClass.toLowerCase().contains(DataSourceType.POSTGRESQL.getType())){
			dbType = DataSourceType.POSTGRESQL.getType();
		} else if (driverClass.toLowerCase().contains(DataSourceType.DM.getType())) {
			dbType = DataSourceType.DM.getType();
		} else if (driverClass.toLowerCase().contains(DataSourceType.OCEANBASE.getType())) {
			dbType = DataSourceType.OCEANBASE.getType();
		} else if (driverClass.toLowerCase().contains(DataSourceType.KINGBASE8.getType())) {
			dbType = DataSourceType.KINGBASE8.getType();
		}
		return dbType;
	}

}
